﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using uTorrentRemote.Net;
using System.Collections.Specialized;
using System.Threading;
using System.IO;

namespace uTorrentRemote.TokenDispatchers
{
    public class RuTrackerDownloadDispatcher : CommonTokenDispatcher, ITokenDispatcher
    {
        public RuTrackerDownloadDispatcher(ILog log)
            : base(log)
        {
        }

        public bool TryToken(Token token)
        {
            string url = token.ToString();

            Regex regex = new Regex(@"http\://rutracker\.org/forum/viewtopic\.php\?t=\d+", RegexOptions.IgnoreCase);
            
            if (!regex.Match(url).Success)
                return false;

            if (!isInitiated)
                init();

            if (urls.ContainsKey(url))
                return false;
            else
            {
                urls[url] = false; // add url with 'not loaded' flag
                log.Write("Added " + url);
            }

            // at this place we have working thread to download urls and update flags

            return true;
        }

        protected override bool tryUrl(string url, int maxTries)
        {
            int cnt = maxTries;
            bool success = false;
            do
            {
                cnt--;

                try
                {
                    log.Write("Trying to download from " + url);
                
                    var bytes_response = client.DownloadData(url);
                    string response = Encoding.UTF8.GetString(bytes_response);

                    Regex regex = new Regex("\"(?<download_link>http\\://dl\\.rutracker\\.org/forum/dl\\.php\\?t=\\d\\d+)\"");
                    Match m = regex.Match(response);
                    if (m.Success)
                    {
                        string download_link = m.Groups["download_link"].Value;
                        downloadToFile(download_link, url);
                        success = true;
                    }
                    else
                    {
                        log.Write("torrent download link not found");
                    }
                }
                catch(Exception ex)
                {
                    log.Write("Exception: " + ex.Message);
                }
                if(!success)
                    Thread.Sleep(60 * 1000);

            }while (!success && cnt > 0);
            return success;
        }
        
        private void downloadToFile(string url, string referer)
        {
            client.Headers.Add("Referer", referer);
            var response = client.UploadValues(url, new NameValueCollection { });
            client.Headers.Remove("Referer");

            string path = getPath();
            
            File.WriteAllBytes(path, response);

            log.Write("Torrent file downloaded from " + url + " to " + path);
        }

        protected override void relogin()
        {
            bool loggedIn = false;

            do
            {
                try
                {
                    client = new WebClientEx();
                    var data = new NameValueCollection
                    {
                        { "login_username", ConfigurationManager.AppSettings["rutracker_login"] },
                        { "login_password", ConfigurationManager.AppSettings["rutracker_password"] },
                        { "login", "%C2%F5%EE%E4" }
                    };

                    var response1 = client.UploadValues("http://login.rutracker.org/forum/login.php", data);
                    string str = Encoding.UTF8.GetString(response1).ToLower();
                    string logged_in_indicator = String.Format("<b class=\"med\">{0}</b>", ConfigurationManager.AppSettings["rutracker_login"]).ToLower();
                    if (str.Contains(logged_in_indicator))
                    {
                        log.Write("OK Logged in to rutracker.org");
                        loggedIn = true;
                    }
                    else
                    {
                        log.Write("ERROR Can't log in to rutracker.org (will keep on trying)");
                        Thread.Sleep(60 * 1000); // wait for 1 minute
                    }
                }
                catch (Exception ex)
                {
                    log.Write("Exception: " + ex.Message);
                    Thread.Sleep(60 * 1000);
                }
            } while (!loggedIn);
        }
    }
}
